﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SDT.Lib.Paging;
using System.Linq.Dynamic;
using System.IO;

namespace SDT.Model
{
    public class ProductManager
    {
        public static IPagedList<Product> GetList(int? typeid,int? catid,int? holidayid, int? priceid,int? eventid, int? timeid, string keyword,
            int hotYN, int pubYN, int saleYN, int newYN, int promotionYN,int dealYN, string order, string orderDir, int page, int pageSize)
        {
            var dataContext = new SDTDataContext();
            var fromDate = DateTime.Now;
            var endDate = DateTime.Now;
            if (timeid > 0) {
                switch (timeid)
                { 
                    case 1:
                        fromDate = DateTime.Now.AddDays(-1); // For Week
                        break;
                    case 2:
                        fromDate = DateTime.Now.AddDays(-3); // For Week
                        break;
                    case 3:
                        fromDate = DateTime.Now.AddDays(-7); // For Week
                        break;
                    case 4:
                        fromDate = DateTime.Now.AddDays(-14); // For Week
                        break;
                    case 5:
                        fromDate = DateTime.Now.AddMonths(-1);// For Month
                        break;
                }
            }
            var l = dataContext.Products
                .Where(a => typeid > 0 ? a.ProductTypeMaps.Where(k=>k.TypeID==typeid).ToList().Count>0 : true)
                .Where(a => holidayid > 0 ? a.ProductHolidayMaps.Where(k => k.HolidayID == holidayid).ToList().Count > 0 : true)
                .Where(a => eventid > 0 ? a.ProductEventMaps.Where(k => k.EventID == eventid).ToList().Count > 0 : true)
                .Where(a => catid > 0 ? a.CatID==catid : true)
                .Where(a => priceid > 0 ? a.ConPriceID == priceid : true)
                .Where(a => timeid > 0 ? a.AddDate>=fromDate && a.AddDate<=endDate : true)
                .Where(a => hotYN > 0 ? a.HotYN == (hotYN == 1 ? true : false) : true)
                .Where(a => pubYN > 0 ? a.PubYN == (pubYN == 1 ? true : false) : true)
                .Where(a => newYN > 0 ? a.NewYN == (newYN == 1 ? true : false) : true)
                .Where(a => saleYN > 0 ? a.SaleYN == (saleYN == 1 ? true : false) : true)
                .Where(a => promotionYN > 0 ? a.PromotionYN == (promotionYN == 1 ? true : false) : true)
                .Where(a => dealYN ==1 ? a.DealYN == true: (dealYN> 1 ? a.DealYN== false ||a.DealYN== null: true))
                .Where(a => keyword == string.Empty ? true : (a.Name.Contains(keyword.ToLower()) || (a.Summary.ToLower().Contains(keyword.ToLower()))))
                .OrderBy(string.Format("{0} {1}", order, orderDir)).AsQueryable();
            var returnVal = l.ToPagedList(page, pageSize);
            return returnVal;
        }
        public static IList<Product> GetList(int? typeid, int? catid, int? holidayid, int? priceid, int? eventid,
            int hotYN, int pubYN, int saleYN, int newYN, int promotionYN,int dealYN,string keyword, string order, string orderDir, int number)
        {
            var dataContext = new SDTDataContext();            
            var l = dataContext.Products
                .Where(a => typeid > 0 ? a.ProductTypeMaps.Where(k => k.TypeID == typeid).ToList().Count > 0 : true)
                .Where(a => holidayid > 0 ? a.ProductHolidayMaps.Where(k => k.HolidayID == holidayid).ToList().Count > 0 : true)
                .Where(a => eventid > 0 ? a.ProductEventMaps.Where(k => k.EventID == eventid).ToList().Count > 0 : true)
                .Where(a => catid > 0 ? a.CatID == catid : true)
                .Where(a => priceid > 0 ? a.ConPriceID == priceid : true)                
                .Where(a => hotYN > 0 ? a.HotYN == (hotYN == 1 ? true : false) : true)
                .Where(a => pubYN > 0 ? a.PubYN == (pubYN == 1 ? true : false) : true)
                .Where(a => newYN > 0 ? a.NewYN == (newYN == 1 ? true : false) : true)
                .Where(a => saleYN > 0 ? a.SaleYN == (saleYN == 1 ? true : false) : true)
                .Where(a => promotionYN > 0 ? a.PromotionYN == (promotionYN == 1 ? true : false) : true)
                .Where(a => dealYN == 1 ? a.DealYN == true : (dealYN > 1 ? a.DealYN == false || a.DealYN == null : true))
                .Where(a => keyword == string.Empty ? true : (a.Name.Contains(keyword.ToLower()) || (a.Summary.ToLower().Contains(keyword.ToLower()))))
                .OrderBy(string.Format("{0} {1}", order, orderDir)).AsQueryable();
            var returnVal = l.Take(number).ToList();
            return returnVal;
        }
        public static IList<Product> GetOtherList(int? id, int? typeid, int? catid, int? holidayid, int? priceid, int? eventid,
            int hotYN, int pubYN, int saleYN, int newYN, int promotionYN, int dealYN, string keyword, string order, string orderDir, int number)
        {
            var dataContext = new SDTDataContext();
            var l = dataContext.Products
                .Where(e=>id>0? e.ID!=id:true)
                .Where(a => typeid > 0 ? a.ProductTypeMaps.Where(k => k.TypeID == typeid).ToList().Count > 0 : true)
                .Where(a => holidayid > 0 ? a.ProductHolidayMaps.Where(k => k.HolidayID == holidayid).ToList().Count > 0 : true)
                .Where(a => eventid > 0 ? a.ProductEventMaps.Where(k => k.EventID == eventid).ToList().Count > 0 : true)
                .Where(a => catid > 0 ? a.CatID == catid : true)
                .Where(a => priceid > 0 ? a.ConPriceID == priceid : true)
                .Where(a => hotYN > 0 ? a.HotYN == (hotYN == 1 ? true : false) : true)
                .Where(a => pubYN > 0 ? a.PubYN == (pubYN == 1 ? true : false) : true)
                .Where(a => newYN > 0 ? a.NewYN == (newYN == 1 ? true : false) : true)
                .Where(a => saleYN > 0 ? a.SaleYN == (saleYN == 1 ? true : false) : true)
                .Where(a => promotionYN > 0 ? a.PromotionYN == (promotionYN == 1 ? true : false) : true)
                .Where(a => dealYN == 1 ? a.DealYN == true : (dealYN > 1 ? a.DealYN == false || a.DealYN == null : true))
                .Where(a => keyword == string.Empty ? true : (a.Name.Contains(keyword.ToLower()) || (a.Summary.ToLower().Contains(keyword.ToLower()))))
                .OrderBy(string.Format("{0} {1}", order, orderDir)).AsQueryable();
            var returnVal = l.Take(number).ToList();
            return returnVal;
        }
        public static IList<Tag> GetTags(int? typeid, int? catid, int? holidayid, int? eventid,
             string order, string orderDir, int number)
        {
            var dataContext = new SDTDataContext();
            var l = dataContext.Tags
                .Where(a => typeid > 0 ? a.ProductTagMaps.Where(e=>e.Product.ProductTypeMaps.Where(k => k.TypeID == typeid).ToList().Count > 0).ToList().Count>0 : true)
                .Where(a => holidayid > 0 ? a.ProductTagMaps.Where(e => e.Product.ProductHolidayMaps.Where(k => k.HolidayID == holidayid).ToList().Count > 0).ToList().Count > 0 : true)
                .Where(a => eventid > 0 ? a.ProductTagMaps.Where(e => e.Product.ProductEventMaps.Where(k => k.EventID == eventid).ToList().Count > 0).ToList().Count > 0 : true)
                .Where(a => catid > 0 ? a.ProductTagMaps.Where(e=>e.Product.CatID == catid).ToList().Count>0 : true)
                .OrderBy(string.Format("{0} {1}", order, orderDir)).AsQueryable();
            var returnVal = l.Take(number).ToList();
            return returnVal;
        }
        public static IPagedList<Product> GetListInTag (int? typeid, int? catid, int? holidayid, int? priceid, int? eventid, int? timeid,int? tagid, string keyword,
           int hotYN, int pubYN, int saleYN, int newYN, int promotionYN,int dealYN, string order, string orderDir, int page, int pageSize)
        {
            var dataContext = new SDTDataContext();
            var fromDate = DateTime.Now;
            var endDate = DateTime.Now;
            if (timeid > 0)
            {
                switch (timeid)
                {
                    case 1:
                        fromDate = DateTime.Now.AddDays(-1); // For Week
                        break;
                    case 2:
                        fromDate = DateTime.Now.AddDays(-3); // For Week
                        break;
                    case 3:
                        fromDate = DateTime.Now.AddDays(-7); // For Week
                        break;
                    case 4:
                        fromDate = DateTime.Now.AddDays(-14); // For Week
                        break;
                    case 5:
                        fromDate = DateTime.Now.AddMonths(-1);// For Month
                        break;
                }
            }
            var l = dataContext.Products
                .Where(a => typeid > 0 ? a.ProductTypeMaps.Where(k => k.TypeID == typeid).ToList().Count > 0 : true)
                .Where(a => holidayid > 0 ? a.ProductHolidayMaps.Where(k => k.HolidayID == holidayid).ToList().Count > 0 : true)
                .Where(a => eventid > 0 ? a.ProductEventMaps.Where(k => k.EventID == eventid).ToList().Count > 0 : true)
                .Where(a => tagid > 0 ? a.ProductTagMaps.Where(k => k.TagID == tagid).ToList().Count > 0 : true)
                .Where(a => catid > 0 ? a.CatID == catid : true)
                .Where(a => priceid > 0 ? a.ConPriceID == priceid : true)
                .Where(a => timeid > 0 ? a.AddDate >= fromDate && a.AddDate <= endDate : true)
                .Where(a => hotYN > 0 ? a.HotYN == (hotYN == 1 ? true : false) : true)
                .Where(a => pubYN > 0 ? a.PubYN == (pubYN == 1 ? true : false) : true)
                .Where(a => newYN > 0 ? a.NewYN == (newYN == 1 ? true : false) : true)
                .Where(a => saleYN > 0 ? a.SaleYN == (saleYN == 1 ? true : false) : true)
                .Where(a => dealYN == 1 ? a.DealYN == true : (dealYN > 1 ? a.DealYN == false || a.DealYN == null : true))
                .Where(a => promotionYN > 0 ? a.PromotionYN == (promotionYN == 1 ? true : false) : true)
                .Where(a => keyword == string.Empty ? true : (a.Name.Contains(keyword.ToLower()) || (a.Summary.ToLower().Contains(keyword.ToLower()))))
                .OrderBy(string.Format("{0} {1}", order, orderDir)).AsQueryable();
            var returnVal = l.ToPagedList(page, pageSize);
            return returnVal;
        }
        public static IPagedList<Product> GetWishlist(string keyword,int customerid, string order, string orderDir, int page, int pageSize)
        {
            var dataContext = new SDTDataContext();            
            var l = dataContext.Products
                .Where(a => customerid > 0 ? a.Wishlists.Where(e=>e.CustomerID==customerid).ToList().Count>0 : true)
                .Where(a => keyword == string.Empty ? true : (a.Name.Contains(keyword.ToLower()) || (a.Summary.ToLower().Contains(keyword.ToLower()))))
                .OrderBy(string.Format("{0} {1}", order, orderDir)).AsQueryable();
            var returnVal = l.ToPagedList(page, pageSize);
            return returnVal;
        }
        public static Product GetProduct(int id)
        {
            try
            {
                var db = new SDTDataContext();
                var p= db.Products.Where(e => e.ID == id).SingleOrDefault();
                return p;
            }
            catch (Exception exp)
            {
                return null;
            }
        }
        public static List<int> GetChild(int catid)
        {
            try
            {
                var db = new SDTDataContext();
                var returnVal = new List<int>();
                var curentCat = db.ProductCategories.Single(o => o.ID == catid);
                returnVal.Add(curentCat.ID);

                foreach (var item in curentCat.ProductCategories)
                {
                    returnVal.AddRange(GetChild(item.ID));
                }

                return returnVal;
            }
            catch (Exception exp)
            {
                return null;
            }
        }
        public static List<ProductCategory> GetObjs(int catid)
        {
            try
            {
                var db = new SDTDataContext();
                var returnVal = new List<ProductCategory>();
                var curentCat = db.ProductCategories.Single(o => o.ID == catid);
                returnVal.Add(curentCat);

                foreach (var item in curentCat.ProductCategories)
                {
                    returnVal.AddRange(GetObjs(item.ID));
                }

                return returnVal;
            }
            catch (Exception exp)
            {
                return null;
            }
        }
        
        public static List<ConvertPrice> GetConvertPrice()
        {
            try
            {
                var db = new SDTDataContext();
                var l = (from c in db.ConvertPrices
                         orderby c.ID ascending
                         select c).ToList();
                return l;
            }
            catch (Exception exp)
            {
                return null;
            }
        }
        
        public static IList<Comment> GetComments(int id, bool? publishYN, int number)
        {
            var dataContext = new SDTDataContext();
            var l = (from c in dataContext.Comments
                     from m in dataContext.CommentsInProducts
                     where c.ID == m.CommentID && m.ProductID == id && (publishYN == null ? true : c.PublishYN == publishYN)
                     orderby c.ID descending
                     select c).Take(number).ToList();
            return l;
        }
        public static void Delete(int id, string path, string thumbPath)
        {
            try
            {
                var dataContext = new SDTDataContext();
                Product pro = dataContext.Products.SingleOrDefault(e => e.ID == id);
                if (pro != null)
                {
                   if (Directory.Exists(path))
                    {
                        // If it doesn't then we just create it before going any further
                        Directory.Delete(path, true);
                    }
                    if (Directory.Exists(thumbPath))
                    {
                        // If it doesn't then we just create it before going any further
                        Directory.Delete(thumbPath, true);
                    }
                    dataContext.CommentsInProducts.DeleteAllOnSubmit(from e in dataContext.CommentsInProducts where e.ProductID == id select e);
                    dataContext.Products.DeleteOnSubmit(pro);
                    dataContext.SubmitChanges();
                }                
            }
            catch (Exception exp)
            {
                throw exp;
            }
        }
    }
}
